package com.lahuan.config.distributed;

/**
 * 按照雪花算法的思路做的简化版<br/>
 * 传统的雪花算法是用二进制位保存各个值<br/>
 * 这里做简化，直接用10进制数字来保存各个数值，更直观<br/>
 * 并且这里只用机器ID做机器的标识，在分布式环境下必须保证每个机器的机器ID都是不一样的。<br/>
 * 机器ID在`application.yml`中配置,key是custom.distributedId <br/>
 *
 * ID生成规则:(从低位开始)<br/>
 * 3位:一个不断迭带的种子,范围[0,999],参考变量seed<br/>
 * 13位:时间戳<br/>
 * 3位:分布式环境下的机器ID,范围[0,999]<br/>
 * 位的分布可以根据实际情况做调整<br/>
 * 如生成的是 1001638705150879995 就代表了:<br/>
 * 机器ID     时间戳        迭带的种子   <br/>
 * 100    1638705150879   995       <br/>
 * 即: 100(机器ID)1638705150879(时间戳)995(迭带的种子)
 */
public class CustomDistributedIdGenerateUtil {

    private volatile static long seed = 995;

    /**
     * @param serverId 服务id 0~999
     * @return
     */
    public static long generate(int serverId) {
        if (serverId > 999 || serverId < 0) {
            throw new RuntimeException("serverId超出大小限制,范围[0,999]");
        }
        long timeMillis = System.currentTimeMillis();
        long res = 0;
        res += serverId * 10_000_000_000_000_000L;
        res += timeMillis * 1000L;
        res += getSeed();
        return res;
    }

    private static synchronized long getSeed() {
        if (seed > 999) {
            seed = 0;
        }
        return seed++;
    }


}
